/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.rafkind.resrev.web.page;

import com.rafkind.resrev.dao.UserDao;
import com.rafkind.resrev.data.Color;
import com.rafkind.resrev.data.User;
import com.rafkind.resrev.web.Authorized;
import com.rafkind.resrev.web.Session;
import com.rafkind.resrev.web.page.component.TitleMenu;
import java.util.Arrays;
import java.util.List;
import org.apache.wicket.Page;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.form.validation.EqualPasswordInputValidator;
import org.apache.wicket.markup.html.form.validation.FormComponentFeedbackBorder;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.apache.wicket.validation.validator.EmailAddressValidator;
import org.jasypt.util.password.BasicPasswordEncryptor;

/**
 *
 * @author Fictional Hero
 */
@Authorized
public class EditUser extends WebPage {
  
  @SpringBean
  private UserDao userDao;
  
  private Model<String> newPassword;
  
  public EditUser(IModel<User> model, final Page previous) {
    super(model);
    
    add(new TitleMenu("titleMenu"));
    newPassword = new Model("");
    
    Form editUserForm = new Form("editUserForm"){

      @Override
      protected void onSubmit() {
        User user = (User) EditUser.this.getDefaultModelObject();
        
        if (newPassword != null 
            && newPassword.getObject() != null 
            && !newPassword.getObject().isEmpty()) {
          String encrypted = new BasicPasswordEncryptor()
            .encryptPassword(newPassword.getObject());
          user.setPassword(encrypted);
        }
        
        userDao.saveUser(user);
        
        setResponsePage(previous);
      }    
    };   
    
    editUserForm.add(new FeedbackPanel("feedback"));
    
    editUserForm.add(new FormComponentFeedbackBorder("loginNameBorder").add(
        new RequiredTextField("loginName", 
        new PropertyModel(model.getObject(), "loginName")){
      @Override
      public boolean isEnabled() {
        return ((Session)getSession()).getCurrentUser().isAdmin();
      }      
    }.setLabel(new Model("Login Name"))));
    
    editUserForm.add(new FormComponentFeedbackBorder("nameBorder").add(
        new RequiredTextField("name", 
        new PropertyModel(model.getObject(), "name")).setLabel(new Model("Name"))));
    
    PasswordTextField pass1 = new PasswordTextField("pass1",
        newPassword);
    pass1.setResetPassword(false);
    pass1.setRequired(model.getObject().isNew());
    pass1.setLabel(new Model("Password"));
    
    PasswordTextField pass2 = new PasswordTextField("pass2");
    pass2.setModel(pass1.getModel());
    pass2.setResetPassword(false);    
    pass2.setRequired(false);
    pass2.setLabel(new Model("Confirmation Password"));
    
    editUserForm.add(new FormComponentFeedbackBorder("pass1Border").add(pass1));
    editUserForm.add(new FormComponentFeedbackBorder("pass2Border").add(pass2));      
    editUserForm.add(new EqualPasswordInputValidator(pass1, pass2));
    
    editUserForm.add(
        new TextField("email", 
        new PropertyModel(model.getObject(), "email"))
          .add(EmailAddressValidator.getInstance()));
    
    editUserForm.add(
        new CheckBox("admin", 
        new PropertyModel(model.getObject(), "admin")){
      @Override
      public boolean isEnabled() {
        return ((Session)getSession()).getCurrentUser().isAdmin();
      }
    });
    
    editUserForm.add(
        new TextField("phone", 
        new PropertyModel(model.getObject(), "phone")));
    
    editUserForm.add(
        new DropDownChoice("authorizor", 
          new AuthorizorModel((User) model.getObject()),
          new UserChoicesModel(userDao),
          new UserDropdownChoiceRenderer()){
      @Override
      public boolean isEnabled() {
        return ((Session)getSession()).getCurrentUser().isAdmin();
      }
    }.setNullValid(false));
    
    editUserForm.add(
        new DropDownChoice("color", 
        new PropertyModel(model.getObject(), "color"),
        Arrays.asList(Color.values())));
    
    editUserForm.add(
        new TextArea("comment", 
        new PropertyModel(model.getObject(), "comment")));
    
    editUserForm.add(
        new Button("saveButton", new PropertyModel(this, "saveButtonText")));
    
    editUserForm.add(
        new Button("cancelButton", new PropertyModel(this, "cancelButtonText")){
      @Override
      public void onSubmit() {
        setResponsePage(previous);
      }
    }.setDefaultFormProcessing(false));
    
    add(editUserForm);    
  }  
  
  public String getSaveButtonText() {
    User u = (User) getDefaultModelObject();
    
    if (u.isNew())
      return "Create new user";
    else
      return "Update user";
  }
  
  public String getCancelButtonText() {
    User u = (User) getDefaultModelObject();
    
    if (u.isNew())
      return "Cancel user creation";
    else
      return "Cancel user update";
  }
  
  public static class AuthorizorModel extends Model<User> {
    
    private User user;
    private User dummyUser;
    
    public AuthorizorModel(User user) {
      super(user.getAuthorizor());
      this.user = user;
      dummyUser = User.createSentinelUser();
    }
    
    @Override
    public User getObject() {
      if (user == null || user.getAuthorizor() == null)
        return dummyUser;
      else
        return user.getAuthorizor();
    }

    @Override
    public void setObject(User newAuthorizor) {      
      if (user != null) {        
        if (newAuthorizor == null || newAuthorizor.equals(dummyUser))
          user.setAuthorizor(null);
        else
          user.setAuthorizor(newAuthorizor);
      }
    }        
  }
  
  public static class UserChoicesModel 
      extends LoadableDetachableModel<List<User>> {
    
    private UserDao userDao;

    public UserChoicesModel(UserDao userDao) {
      this.userDao = userDao;
    }
    
    @Override
    protected List<User> load() {
      List<User> users = (List<User>) userDao.getAllUsers();
      users.add(0, User.createSentinelUser());
      return users;
    }  
  }
  
  public static class UserDropdownChoiceRenderer 
      implements IChoiceRenderer<User> {

    public Object getDisplayValue(User user) {
      return user.getName();
    }

    public String getIdValue(User user, int arg1) {
      return user.getId().toString();      
    }   
  }
}